﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using System.Threading;

namespace SetAndGetControlProperty
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "..\\..\\..\\AppTest\\bin\\debug\\AppTest.exe";
            string formname = "AppTest.Form1";

            Prompt("Launch app...");
            Form f = LaunchApp(filename, formname);

            Prompt("Set textbox value.....");

            DSetControlPropertyValue dset = new DSetControlPropertyValue(SetControlPropertyValue);
            object[] o = new object[] { f,"tb_Name","Text","hello world"};
            f.Invoke(dset,o);

            Prompt("Get textbox value...");

            DGetControlPropertyValue dget = new DGetControlPropertyValue(GetControlPropertyValue);
            o = new object[] { f,"tb_Name","Text"};
            string text = (string)f.Invoke(dget, o);

            Console.WriteLine("test is "+text);
            Console.ReadLine();


        }

        private static BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;

        private delegate object DGetControlPropertyValue(Form f, string controlname, string propertyname);

        private static object GetControlPropertyValue(Form f, string controlname, string propertyname)
        {
            Type t = f.GetType();
            FieldInfo fi = t.GetField(controlname,Flags);
            object obj = fi.GetValue(f);
            t = obj.GetType();
            PropertyInfo pi = t.GetProperty(propertyname);
            return pi.GetValue(obj);
        }

        private delegate void DSetControlPropertyValue(Form f, string controlname, string propertyname, string newalue);

        private static void SetControlPropertyValue(Form f, string controlname, string propertyname, object newvalue)
        {
            Type t = f.GetType();
            FieldInfo fi = t.GetField(controlname,Flags);
            object obj = fi.GetValue(f);
            t = obj.GetType();
            PropertyInfo pi = t.GetProperty(propertyname);
            pi.SetValue(obj, newvalue, null);
        }

        private static void Prompt(string display)
        {

            Console.WriteLine(display);
            Console.ReadLine();
        }

        private static Form LaunchApp(string filename, string formname)
        {
            Assembly assembly = Assembly.LoadFrom(filename);
            Type t = assembly.GetType(formname);

            Form f = (Form)assembly.CreateInstance(t.FullName);

            AppState aps = new AppState(f);
            ThreadStart ts = new ThreadStart(aps.AppRun);
            Thread thread = new Thread(ts);
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();

            return f;
        }

        
    }

    class AppState
    {
        private Form form;
        public AppState(Form f)
        {
            form = f;


        }
        public void AppRun()
        {
            Application.Run(form);
        }
    }
}
